/**
 * Property & Copyright 2009 Nokia Siemens Networks.
 */ 
package com.nsn.das.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.nsn.das.AppCtxHolder;

import javax.sql.DataSource;

public class SpringUtils {
	private static Log log = LogFactory.getLog(SpringUtils.class);
	private static final ApplicationContext ctx = AppCtxHolder.getApplicationContext();
	
	public static Object getBean(String name) {
		if(ctx != null) {
			return ctx.getBean(name);
		}
		throw new IllegalStateException("Spring application context not initialized");
	}
	
	public static ApplicationContext getApplicationContext() {
		return ctx;
	}
    
	public static HibernateTransactionManager getTransactionManager() {
        return (HibernateTransactionManager)ctx.getBean("transactionManager3");        
    }
	
    public static SessionFactory getSessionFactory() {
        return (SessionFactory) AppCtxHolder.getApplicationContext().getBean("sessionFactory3");        
    }

    private static SessionFactory getNewSessionFactory() {
        org.springframework.orm.hibernate3.HibernateTransactionManager mgr = 
            (org.springframework.orm.hibernate3.HibernateTransactionManager) SpringUtils.getBean("transactionManager3");
        return mgr.getSessionFactory();
    }
    
    public static HibernateTemplate getNewHibernateTemplate() {
        return new HibernateTemplate(getNewSessionFactory());
    }
    
    public static HibernateTemplate getHibernateTemplate() {
        return new HibernateTemplate(getSessionFactory());
    }

    public static JdbcTemplate getJdbcTemplate() {
        return new JdbcTemplate((DataSource)getBean("jdbcDataSource"));
    }
    
    public static TransactionStatus beginTransaction(HibernateTransactionManager manager) {
		if (manager != null) {
			// starts a new transaction			
			return manager.getTransaction(null);
		}
		return null;
    }
    
    public static void commit(TransactionStatus s, HibernateTransactionManager manager) {
		try {		
			// commit the transaction
			if (!s.isRollbackOnly())
				manager.commit(s);
			else
				manager.rollback(s);
		} catch (Exception e) {
			log.error("Error in commit", e);
		}
    }
    
    public static void rollback(TransactionStatus s, HibernateTransactionManager manager) {
    	try {		
			manager.rollback(s);
		}
    	catch (Exception re) {
			log.error("Error in rollback", re);
		}
    }
    
	public static void setRollbackOnly() {
		HibernateTransactionManager mgr = 
			(HibernateTransactionManager)SpringUtils.getBean("transactionManager3");
		
		TransactionTemplate tt = new TransactionTemplate(mgr);
		tt.execute(new TransactionCallbackWithoutResult() {
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				status.setRollbackOnly();
			}
		});
	}

    
    /**
     * Creates a string for inner query parameters containing specified amoun of question
     * marks.
     * ie. result of <code>getInnerQuery(5)</code> is "(?,?,?,?,?)"
     * @param size The desired amount of question marks
     * @return string for inner query parameters
     */
    public static String getInnerQuery(int size) {
    	StringBuffer in = new StringBuffer(512);
    	in.append("(");
    	for (int i=0 ; i<size; i++) {
    		in.append("?");
    		if (i<size-1) in.append(",");
    	}
    	in.append(")");
    	return in.toString();
    }
    
    public static String getOrderByIdString(Object[] ids)
    {
    	if(ids==null || ids.length==0)
    		return "id";
    	StringBuffer orderby = new StringBuffer();
    	orderby.append("field(id,");
    	for (int i=0 ; i<ids.length; i++) {
    		orderby.append(""+ids[i]);
    		if (i<ids.length-1) orderby.append(",");
    	}
    	orderby.append(")");
    	return orderby.toString();
    }
}
